/*     */ package com.zimbra.cs.mailbox;
/*     */ 
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Server;
/*     */ import com.zimbra.cs.util.Config;
/*     */ import com.zimbra.cs.util.Zimbra;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Collections;
/*     */ import java.util.HashSet;
/*     */ import java.util.List;
/*     */ import java.util.Set;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class PurgeThread
/*     */   extends Thread
/*     */ {
/*  44 */   private static volatile PurgeThread sPurgeThread = null;
/*  45 */   private static Object THREAD_CONTROL_LOCK = new Object();
/*  46 */   private boolean mShutdownRequested = false;
/*     */   
/*     */   private PurgeThread() {
/*  49 */     setName("MailboxPurge");
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public static synchronized void startup()
/*     */   {
/*  56 */     synchronized (THREAD_CONTROL_LOCK) {
/*  57 */       if (isRunning()) {
/*  58 */         ZimbraLog.purge.warn("Cannot start a second purge thread while another one is running.");
/*  59 */         return;
/*     */       }
/*     */       
/*  62 */       if (getSleepInterval() == 0L) {
/*  63 */         ZimbraLog.purge.info("Not starting purge thread because %s is 0.", new Object[] { "zimbraMailPurgeSleepInterval" });
/*     */         
/*  65 */         return;
/*     */       }
/*     */       
/*     */       try
/*     */       {
/*  70 */         String displayInterval = Provisioning.getInstance().getLocalServer().getAttr("zimbraMailPurgeSleepInterval", null);
/*     */         
/*  72 */         ZimbraLog.purge.info("Starting purge thread with sleep interval %s.", new Object[] { displayInterval });
/*     */       } catch (ServiceException e) {
/*  74 */         ZimbraLog.purge.warn("Unable to get %s.  Aborting thread startup.", "zimbraMailPurgeSleepInterval", e);
/*     */         
/*  76 */         return;
/*     */       }
/*     */       
/*     */ 
/*  80 */       sPurgeThread = new PurgeThread();
/*  81 */       sPurgeThread.start();
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public static synchronized boolean isRunning()
/*     */   {
/*  89 */     synchronized (THREAD_CONTROL_LOCK) {
/*  90 */       if (sPurgeThread != null) {
/*  91 */         return true;
/*     */       }
/*  93 */       return false;
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   public static synchronized void shutdown()
/*     */   {
/* 102 */     synchronized (THREAD_CONTROL_LOCK) {
/* 103 */       if (sPurgeThread != null) {
/* 104 */         sPurgeThread.requestShutdown();
/* 105 */         sPurgeThread.interrupt();
/* 106 */         sPurgeThread = null;
/*     */       } else {
/* 108 */         ZimbraLog.purge.debug("shutdown() called, but purge thread is not running.");
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void run()
/*     */   {
/* 120 */     long sleepTime = LC.purge_initial_sleep_ms.longValue();
/* 121 */     ZimbraLog.purge.info("Purge thread sleeping for %dms before doing work.", new Object[] { Long.valueOf(sleepTime) });
/*     */     try
/*     */     {
/* 124 */       Thread.sleep(sleepTime);
/*     */     } catch (InterruptedException e) {
/* 126 */       ZimbraLog.purge.info("Shutting down purge thread.");
/* 127 */       sPurgeThread = null;
/* 128 */       return;
/*     */     }
/*     */     
/* 131 */     Set<Integer> purgePendingMailboxes = new HashSet();
/*     */     for (;;) {
/* 133 */       List<Integer> mailboxIds = getMailboxIds();
/* 134 */       boolean slept = false;
/*     */       
/* 136 */       for (int i = 0; i < mailboxIds.size(); i++) {
/* 137 */         int mailboxId = ((Integer)mailboxIds.get(i)).intValue();
/* 138 */         if (this.mShutdownRequested) {
/* 139 */           ZimbraLog.purge.info("Shutting down purge thread.");
/* 140 */           sPurgeThread = null;
/* 141 */           return;
/*     */         }
/* 143 */         ZimbraLog.addMboxToContext(mailboxId);
/*     */         
/*     */ 
/* 146 */         boolean attemptedPurge = false;
/*     */         try {
/* 148 */           MailboxManager mm = MailboxManager.getInstance();
/* 149 */           if ((mm.isMailboxLoadedAndAvailable(mailboxId)) || (purgePendingMailboxes.contains(Integer.valueOf(mailboxId)))) {
/* 150 */             attemptedPurge = true;
/* 151 */             Mailbox mbox = mm.getMailboxById(mailboxId);
/* 152 */             Account account = mbox.getAccount();
/* 153 */             Provisioning prov = Provisioning.getInstance();
/* 154 */             if ((!"maintenance".equals(account.getAccountStatus(prov))) && (!account.isIsExternalVirtualAccount()))
/*     */             {
/* 156 */               ZimbraLog.addAccountNameToContext(account.getName());
/* 157 */               boolean purgedAll = mbox.purgeMessages(null);
/* 158 */               if (!purgedAll) {
/* 159 */                 ZimbraLog.purge.info("Not all messages were purged.  Scheduling mailbox to be purged again.");
/* 160 */                 mailboxIds.add(Integer.valueOf(mailboxId));
/*     */               }
/* 162 */               Config.setInt("purge.lastMailboxId", mbox.getId());
/*     */             } else {
/* 164 */               ZimbraLog.purge.debug("Skipping mailbox %d because the account is in maintenance status or is an external virtual account.", new Object[] { Integer.valueOf(mailboxId) });
/*     */             }
/*     */           } else {
/* 167 */             ZimbraLog.purge.debug("Skipping mailbox %d because it is not loaded into memory.", new Object[] { Integer.valueOf(mailboxId) });
/*     */           }
/*     */         } catch (ServiceException se) {
/* 170 */           if ("service.WRONG_HOST".equals(se.getCode())) {
/* 171 */             if (ZimbraLog.purge.isDebugEnabled()) {
/* 172 */               ZimbraLog.purge.debug("not purging mailbox moved to other host ", se);
/*     */             } else {
/* 174 */               ZimbraLog.purge.info("not purging mailbox %d; account moved to another host", new Object[] { Integer.valueOf(mailboxId) });
/*     */             }
/*     */           } else {
/* 177 */             ZimbraLog.purge.warn("Unable to purge mailbox %d", Integer.valueOf(mailboxId), se);
/*     */           }
/*     */         } catch (OutOfMemoryError oome) {
/* 180 */           Zimbra.halt("Ran out of memory while purging mailboxes", oome);
/*     */         } catch (Throwable t) {
/* 182 */           ZimbraLog.purge.warn("Unable to purge mailbox %d", Integer.valueOf(mailboxId), t);
/*     */         }
/*     */         
/* 185 */         ZimbraLog.clearContext();
/* 186 */         if (attemptedPurge)
/*     */         {
/* 188 */           sleep();
/* 189 */           slept = true;
/*     */         }
/*     */       }
/*     */       
/*     */ 
/* 194 */       if (!slept) {
/* 195 */         sleep();
/*     */       }
/*     */       try
/*     */       {
/* 199 */         long lastPurgeMaxDuration = Provisioning.getInstance().getLocalServer().getLastPurgeMaxDuration();
/* 200 */         purgePendingMailboxes = MailboxManager.getInstance().getPurgePendingMailboxes(System.currentTimeMillis() - lastPurgeMaxDuration);
/*     */       } catch (ServiceException e) {
/* 202 */         ZimbraLog.purge.warn("Unable to get purge pending mailboxes ", e);
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   private void sleep()
/*     */   {
/* 212 */     long interval = getSleepInterval();
/* 213 */     ZimbraLog.purge.debug("Sleeping for %d milliseconds.", new Object[] { Long.valueOf(interval) });
/*     */     
/* 215 */     if (interval > 0L) {
/*     */       try {
/* 217 */         Thread.sleep(interval);
/*     */       } catch (InterruptedException e) {
/* 219 */         ZimbraLog.purge.debug("Purge thread was interrupted.");
/* 220 */         this.mShutdownRequested = true;
/*     */       }
/*     */     } else {
/* 223 */       this.mShutdownRequested = true;
/*     */     }
/*     */   }
/*     */   
/*     */   private void requestShutdown() {
/* 228 */     this.mShutdownRequested = true;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 235 */   private static long sSleepInterval = 0L;
/*     */   
/*     */ 
/*     */ 
/*     */   private static long getSleepInterval()
/*     */   {
/*     */     try
/*     */     {
/* 243 */       Provisioning prov = Provisioning.getInstance();
/* 244 */       Server server = prov.getLocalServer();
/* 245 */       sSleepInterval = server.getTimeInterval("zimbraMailPurgeSleepInterval", 0L);
/*     */     } catch (ServiceException e) {
/* 247 */       ZimbraLog.purge.warn("Unable to determine value of %s.  Using previous value: %d.", "zimbraMailPurgeSleepInterval", Long.valueOf(sSleepInterval), e);
/*     */     }
/*     */     
/*     */ 
/* 251 */     return sSleepInterval;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   private List<Integer> getMailboxIds()
/*     */   {
/* 259 */     List<Integer> mailboxIds = new ArrayList();
/*     */     
/*     */     try
/*     */     {
/* 263 */       for (int id : MailboxManager.getInstance().getMailboxIds()) {
/* 264 */         mailboxIds.add(Integer.valueOf(id));
/*     */       }
/* 266 */       Collections.sort(mailboxIds);
/*     */       
/*     */ 
/* 269 */       int lastId = Config.getInt("purge.lastMailboxId", 0);
/* 270 */       for (int i = 0; i < mailboxIds.size(); i++) {
/* 271 */         if (((Integer)mailboxIds.get(i)).intValue() > lastId) {
/* 272 */           Collections.rotate(mailboxIds, -i);
/* 273 */           break;
/*     */         }
/*     */       }
/*     */     }
/*     */     catch (ServiceException e) {
/* 278 */       ZimbraLog.purge.warn("Unable to get mailbox id's", e);
/* 279 */       return Collections.emptyList();
/*     */     }
/*     */     
/* 282 */     return mailboxIds;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/mailbox/PurgeThread.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */